package com.haltakov.letterjumble.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import com.haltakov.letterjumble.game.api.BoardWord;
import com.haltakov.letterjumble.game.api.Letter;
import com.haltakov.letterjumble.game.api.WordDirection;

/* A threaded server specialised to deal with at most two
concurrent links from the two players involved in the
FourByFour game.

This is a thin server -- all the game logic is located
on the client-side.

The shared data is an array of references to the handlers
and the current number of players. Since this is so little,
a shared object is not used to maintain it. 
*/

public class LetterJumbleServer {
	
	private static final int PORT = 1234;
	
	private static final int MAX_PLAYERS = 4; 
	private static final int MIN_PLAYERS = 2; 

	private final static int PLAYER1 = 1;
	private final static int PLAYER2 = 2;
	private final static int PLAYER3 = 3;
	private final static int PLAYER4 = 4; // use to be MACHINE

	// data structures shared by the handlers
	private PlayerServerHandler[] handlers; // handlers for players
	private int numPlayers;
	  
	private ServerSocket serverSocket;
	
	public LetterJumbleServer() {
	
		handlers = new PlayerServerHandler[MAX_PLAYERS];
	    handlers[0] = null;
	    handlers[1] = null;
	    numPlayers = 0;
	    
		// set up ServerSocket
		try {
			serverSocket = new ServerSocket(PORT);
			Socket clientSock;
			while (true) {
		        System.out.println("Waiting for a client...");
		        clientSock = serverSocket.accept();
		        System.out.println("accept new client: " + clientSock);
		        new PlayerServerHandler(clientSock, this).start();
		      }
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	// methods for child threads to access shared data structures

	synchronized public boolean enoughPlayers() {
		return (numPlayers <= MAX_PLAYERS && numPlayers >= MIN_PLAYERS);
	}

	synchronized public int addPlayer(PlayerServerHandler h) {
	/*
	 * Store a reference to the handler, and return a player ID to the handler.
	 * The ID is the array index where the handler is stored + 1.
	 */
		if(numPlayers < MAX_PLAYERS) {
			handlers[numPlayers] = h;
			numPlayers++;
			return numPlayers;
		}
//		for (int i = 0; i < MAX_PLAYERS; i++)
//			if (handlers[i] == null) {
//				handlers[i] = h;
//				numPlayers++;
//				return i + 1; // playerID is 1 or 2 (array index + 1)
//			}
		return -1; // means we have enough players already
	}

	synchronized public void removePlayer(int playerID) {
		handlers[playerID - 1] = null; // no checking done of player value
		numPlayers--;
	}

	synchronized public void tellOther(int playerID, String msg) { // send mesg to the other player
		int otherID = ((playerID == PLAYER1) ? PLAYER2 : PLAYER1);
		if (handlers[otherID - 1] != null) // index is ID-1
			handlers[otherID - 1].sendMessage(msg);
	}

	// -----------------------------------

	public static void main(String args[]) {
		new LetterJumbleServer();
	}

	public void startTheGame() {
		for(PlayerServerHandler handler : handlers) {
			if(handler != null) {	
				handler.sendMessage("start " + 1);
			}
		}
	}

	public void getFromOther(int playerID, String msg) {
		try {
		if (handlers[playerID-2] != null)
			handlers[playerID-1].sendMessage(msg);
		}catch (Throwable t) {
			//t.printStackTrace();
		}
	}
}

